﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Pex.Framework;


namespace Benchmarks.McMinnThesisBen
{
    [TestClass]
    public class Sortcode
    {
        static int RESULT_ENTER_NEW_CHAR = 0;
        static int RESULT_VALID = 1;
        static int RESULT_INVALID = 2;

        bool digit_set_1, digit_set_2, digit_set_3, dash_1, dash_2, end;
        int pos;

        public Sortcode()
        {
            digit_set_1 = true;
            digit_set_2 = false;
            digit_set_3 = false;
            dash_1 = false;
            dash_2 = false;
            end = false;
            pos = 0;
        }

        private bool is_digit(int unicode_char)
        {
            if (unicode_char >= 48 && unicode_char <= 57)
                return true;
            else
                return false;
        }
        
        private bool is_dash(int unicode_char)
        {
            if (unicode_char == 45)
                return true;
            else
                return false;
        }

        private bool is_lf(int unicode_char)
        {
            if (unicode_char == 12)
                return true;
            else
                return false;
        }

        public int validate_sortcode(int unicode_char)
        {
            int result = RESULT_ENTER_NEW_CHAR;
            if (is_digit(unicode_char))
            {
                if (digit_set_1 && pos == 1)
                {
                    digit_set_1 = false;
                    dash_1 = true;
                }
                else if (digit_set_2 && pos == 4)
                {
                    digit_set_2 = false;
                    dash_2 = true;
                }
                else if (digit_set_3 && pos == 7)
                {
                    digit_set_3 = false;
                    end = true;
                }
                if (pos != 2 && pos != 5)
                {
                    pos++;
                }
                else
                {
                    result = RESULT_INVALID;
                }
            }
            else if (is_dash(unicode_char))
            {
                if (dash_1)
                {
                    dash_1 = false;
                    digit_set_2 = true;
                }
                else if (dash_2)
                {
                    dash_2 = false;
                    digit_set_3 = true;
                }
                if (pos == 2 || pos == 5)
                {
                    pos++;
                }
                else
                {
                    result = RESULT_INVALID;
                }
            }
            else if (is_lf(unicode_char) && end && pos == 8)
            {
                result = RESULT_VALID;
                digit_set_1 = true;
                end = false;
                pos = 0;
            }
            else
            {
                result = RESULT_INVALID;
            }
            return result;
        }

        //run with C:\pex\bin\Debug>Pex Benchmarks.dll /mf:TestSortcodeFitness
        // adding /fte outputs all generated tests
        //[PexMethod(MaxRuns = 100, MaxConditions = int.MaxValue, MaxRunsWithoutNewTests = int.MaxValue)]        
        //public void TestSortcodeFitness(int[] chars)
        //{
        //    TestSortcode(chars);
        //}

        //run with C:\pex\bin\Debug>Pex Benchmarks.dll /mf:TestSortcodeDefault
        // adding /fte outputs all generated tests
        //[PexMethod(MaxRuns = 100, MaxConditions = int.MaxValue, MaxRunsWithoutNewTests = int.MaxValue)]
        //public void TestSortcodeDefault(int[] chars)
        //{
        //    TestSortcode(chars);
        //}

        //private void TestSortcode(int[] chars)
        //{
        //    PexAssume.IsTrue(chars != null);

        //    Sortcode c = new Sortcode();
        //    for (int i = 0; i <= (chars.Length - 1); i++)
        //        c.validate_sortcode(chars[i]);
        //}
    }
}
